#include "fw.img\fw.img.h"
#include "fw.xml\fw.xml.h"
#include "fw.pdf\fw.pdf.h"
#include "util.h"
#include "Layout\Layout.h"

int test( int argc, char** argv )
{
	int result = 0;
	//result |= test_img( argc, argv );
	result |= test_xml( argc, argv );
	result |= test_pdf( argc, argv );
	return result;
}

int run( int argc, char** argv )
{
	if( argc < 4 )
	{
		ERROR("Not enough arguments!\n");
		ERROR("args: xml image pdf [showText] [fontScale <x>]\n");
		return 1;
	}

	bool showText = false;

	if( argc > 4 )
	{
		for( unsigned char i = 4; i < argc; i++ )
		{
			if( !strcmp( argv[i], "showText" ) )
			{
				showText = true;
			}
			if( !strcmp( argv[i], "fontScale" ) && argc > i+1 )
			{
				float x;
				x = atof( argv[i+1] );
				setFontScale( x );
				i++;
			}
		}
	}

	InitializeMagick ( *argv );

	TiXmlDocument doc( argv[1] );
	if(!doc.LoadFile())
	{
		ERROR("Could not load XML!\n");
		return 1;
	}

	TiXmlNode *alto = doc.FirstChild( "alto" );

	if( !alto )
	{
		ERROR("Invalid input xml!\n");
		return 1;
	}

	HPDF_Doc  pdf;
    HPDF_Page page;
	HPDF_Image image;

    pdf = HPDF_New (error_handler, NULL);
    if (!pdf) {
        printf ("error: cannot create PdfDoc object\n");
        return 1;
    }

    if (setjmp(env)) {
        HPDF_Free (pdf);
        return 1;
    }

	HPDF_SetCompressionMode (pdf, HPDF_COMP_ALL);

	Image test;
	try
	{
		test.read ( argv[2] );
		test.write( "tmp.jpg" );
		//HPDF_BYTE *pixels = (unsigned char*) malloc( sizeof(unsigned char) * 3 * test.baseColumns() * test.baseRows() );
		//if( !pixels )
		//{
		//	ERROR("Could not alloc mem!\n");
		//	return 1;
		//}
		//test.writePixels( RGBQuantum, pixels );
		//image = HPDF_LoadRawImageFromMem( pdf, pixels, test.baseColumns(), test.baseRows(), HPDF_CS_DEVICE_RGB, 8 );
		//free( pixels );
		image = HPDF_LoadJpegImageFromFile( pdf, "tmp.jpg" );
	}
	catch ( Exception &err )
	{
		ERROR("Caught exception: %s\n",err.what());
		return 1;
	}

	unsigned long count_ok = 0;
	unsigned long count = 0;

	for(TiXmlElement *e = alto->FirstChildElement();e;e=e->NextSiblingElement())
	{
		const char *elem = e->Value();
		if(!strcmp(elem,"Description"))
		{
			//read description
		}
		else if(!strcmp(elem,"Styles"))
		{
			//read styles
			TiXmlNode *child = e->FirstChildElement();
			while(child)
			{
				if(!strcmp(child->Value(),"TextStyle"))
				{
					ASSERT(!readLayoutStyle(child->ToElement()));
				}
				child = child->NextSibling();
			}
		}
		else if(!strcmp(elem,"Layout"))
		{
			//read layouts
			TiXmlNode *child = e->FirstChildElement();
			while( child )
			{
				if( !strcmp(child->Value(),"Page") )
				{
					page = HPDF_AddPage (pdf);

					HPDF_REAL mywidth = 0;
					HPDF_REAL myheight = 0;

					TiXmlAttribute* pAttrib=child->ToElement()->FirstAttribute();
					while (pAttrib)
					{
						if( !strcmp( pAttrib->Name(), "WIDTH" ) )
						{
							mywidth = atof( pAttrib->Value() );
						}
						else if( !strcmp( pAttrib->Name(), "HEIGHT" ) )
						{
							myheight = atof( pAttrib->Value() );
						}
						pAttrib = pAttrib->Next();
					}

					ASSERT( mywidth );
					ASSERT( myheight );

					HPDF_Page_SetWidth( page, mywidth );
					HPDF_Page_SetHeight( page, myheight );

					HPDF_Page_DrawImage ( page, image, 0, 0, mywidth, myheight );

					if( !showText )
					{
						HPDF_Page_SetTextRenderingMode( page, HPDF_INVISIBLE );
					}

					HPDF_REAL werr = mywidth / 1000.0f;
					HPDF_REAL herr = myheight / 1000.0f;

					HPDF_Page_BeginText (page);

					TiXmlNode *child1 = child->FirstChildElement();
					while( child1 )
					{
						if( !strcmp(child1->Value(),"PrintSpace") )
						{
							TiXmlNode *child2 = child1->FirstChildElement();
							while( child2 )
							{
								if( !strcmp(child2->Value(),"TextBlock") )
								{
									char block_layout[50] = "";
									HPDF_TextAlignment block_align = HPDF_TALIGN_CENTER;
									TiXmlAttribute* pAttrib=child2->ToElement()->FirstAttribute();
									while (pAttrib)
									{
										if( !strcmp( pAttrib->Name(), "STYLEREFS" ) )
										{
											char *s = strstr( (char*)pAttrib->Value(), "TXT_" );
											if( s )
											{
												size_t x = strcspn(s," ");
												if( x )
												{
													strncpy( block_layout, s, x );
													block_layout[ x ] = 0;
												}
												else
												{
													ASSERT(0);
													strncpy( block_layout, s, strlen(s) );
													block_layout[ strlen(s) ] = 0;
												}
											}
											if( strstr( pAttrib->Value(), "PAR_CENTER" ) )
											{
												block_align = HPDF_TALIGN_CENTER;
											}
											else if( strstr( pAttrib->Value(), "PAR_LEFT" ) )
											{
												block_align = HPDF_TALIGN_LEFT;
											}
											else if( strstr( pAttrib->Value(), "PAR_RIGHT" ) )
											{
												block_align = HPDF_TALIGN_RIGHT;
											}
											else if( strstr( pAttrib->Value(), "PAR_BLOCK" ) )
											{
												block_align = HPDF_TALIGN_JUSTIFY;
											}


											break;
										}
										pAttrib = pAttrib->Next();
									}


									TiXmlNode *child3 = child2->FirstChildElement();
									while( child3 )
									{
										if( !strcmp(child3->Value(),"TextLine") )
										{
											TiXmlNode *child4 = child3->FirstChildElement();
											while( child4 )
											{
												if( !strcmp(child4->Value(),"String") )
												{
													//HPOS="721" VPOS="326" WIDTH="1967" HEIGHT="150" CONTENT="DAGBLAD" STYLEREFS="TXT_"
													HPDF_REAL top = 0;
													HPDF_REAL left = 0;
													HPDF_REAL right = 0;
													HPDF_REAL bottom = 0;
													char *str = NULL;
													char layout[50];
													HPDF_TextAlignment align = block_align;
													strcpy( layout, block_layout );
													TiXmlAttribute* pAttrib=child4->ToElement()->FirstAttribute();
													while (pAttrib)
													{
														if( !strcmp( pAttrib->Name(), "HPOS" ) )
														{
															left = atof( pAttrib->Value() );
														}
														else if( !strcmp( pAttrib->Name(), "VPOS" ) )
														{
															top = atof( pAttrib->Value() );
														}
														else if( !strcmp( pAttrib->Name(), "WIDTH" ) )
														{
															right = atof( pAttrib->Value() );
														}
														else if( !strcmp( pAttrib->Name(), "HEIGHT" ) )
														{
															bottom = atof( pAttrib->Value() );
														}
														else if( !strcmp( pAttrib->Name(), "CONTENT" ) )
														{
															str = (char*) malloc( strlen( pAttrib->Value() ) + 1 );
															strcpy( str, pAttrib->Value() );
															str[ strlen(pAttrib->Value()) ] = 0;
														}
														else if( !strcmp( pAttrib->Name(), "STYLEREFS" ) )
														{
															char *s = strstr( (char*)pAttrib->Value(), "TXT_" );
															if( s )
															{
																size_t x = strcspn(s," ");
																if( x )
																{
																	strncpy( layout, s, x );
																	layout[ x ] = 0;
																}
																else
																{
																	ASSERT(0);
																	strncpy( layout, s, strlen(s) );
																	layout[ strlen(s) ] = 0;
																}
															}
															if( strstr( pAttrib->Value(), "PAR_CENTER" ) )
															{
																align = HPDF_TALIGN_CENTER;
															}
															else if( strstr( pAttrib->Value(), "PAR_LEFT" ) )
															{
																align = HPDF_TALIGN_LEFT;
															}
															else if( strstr( pAttrib->Value(), "PAR_RIGHT" ) )
															{
																align = HPDF_TALIGN_RIGHT;
															}
															else if( strstr( pAttrib->Value(), "PAR_BLOCK" ) )
															{
																align = HPDF_TALIGN_JUSTIFY;
															}														
														}
														pAttrib = pAttrib->Next();
													}
													left = left;
													top = (myheight - top);
													right = left + right + werr;
													bottom = top - bottom - herr;
													ASSERT(!applyLayout( pdf, page, layout ));
													HPDF_UINT cw = 0;
													HPDF_Page_TextRect( page, left, top, right, bottom, str, align, &cw );
													//ASSERT( cw == strlen( str ) );
													count_ok += cw == strlen( str );
													count++;
													if( str ) free( str );
												}
												child4 = child4->NextSibling();
											}
										}
										child3 = child3->NextSibling();
									}
								}
								child2 = child2->NextSibling();
							}
						}
						child1 = child1->NextSibling();
					}

					HPDF_Page_EndText (page);
				}
				child = child->NextSibling();
			}
		}
		else
		{
			//not good
			ERROR("Unknown element found %s\n",elem);
			return 1;
		}
	}

    HPDF_SaveToFile (pdf, argv[3]);

    /* clean up */
    HPDF_Free (pdf);

	printf("%d/%d strings printed\n",count_ok,count);

	printf("Done\n");
	getchar();
	return 0;
}

int main( int argc, char **argv )
{
	return run( argc, argv );
}